#include "slam_ros/clear_log.h"

#include <glog/logging.h>
#include <algorithm>

namespace slam_ros {

ClearLogFile::ClearLogFile(
    const std::vector<LogFilePathAndMaxNum> &log_path_and_retained_num)
    : log_path_and_retained_num_(log_path_and_retained_num) {}

ClearLogFile::~ClearLogFile() {}

void ClearLogFile::RemoveOldLogFIle(const std::string &dir_name,
                                    const int retained_num) {
  if (retained_num <= 0) {
    LOG(ERROR) << "Retain num is negative value.";
    return;
  }
  std::vector<FileAndTime> all_files;
  GetAllFileAndTimeInDir(dir_name, &all_files);

  if (all_files.size() <= retained_num) {
    return;
  }

  std::sort(all_files.begin(), all_files.end(),
            [](const FileAndTime &a, const FileAndTime &b) {
              return a.file_time < b.file_time;
            });

  const int excess_num = all_files.size() - retained_num;
  for (auto iter = all_files.begin();
       iter != all_files.begin() + excess_num + 1;) {
    remove(iter->file_name.c_str());
    LOG(WARNING) << "Remove " << iter->file_name;
    ++iter;
  }
}

void ClearLogFile::AutoRemoveOldLogFIle() {
  for (const auto &item : log_path_and_retained_num_) {
    RemoveOldLogFIle(item.path, item.retained_num);
  }
}

void ClearLogFile::GetAllFileAndTimeInDir(const std::string &dir_name,
                                          std::vector<FileAndTime> *files) {
  if (dir_name == "." || dir_name == "..") return;

  auto &all_files = *files;
  all_files.clear();

  DIR *dp;
  struct dirent *ep;
  dp = opendir(dir_name.c_str());
  int count = 0;
  while ((ep = readdir(dp)) != NULL) {
    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) {
      continue;
    }

    const std::string current_file = dir_name + "/" + ep->d_name;

    if (access(current_file.c_str(), 0) == -1) {
      LOG(ERROR) << "File " << current_file << " does not exist!";
      continue;
    }

    FILE *fp;
    int fd;
    struct stat buf;
    fp = fopen(current_file.c_str(), "r");
    fd = fileno(fp);
    fstat(fd, &buf);
    all_files.emplace_back(FileAndTime(current_file, buf.st_mtime));
    fclose(fp);
  }
  closedir(dp);
}
}  // namespace slam_ros